/**
 * @Author ZhangGJ
 * @Date 2021/11/14 09:49
 */
#include "friend_currency.h"
#include "../../exception/exception.h"

Currency::Currency(SignType theSign, unsigned long theDollars, unsigned int theCents)
{
    setValue(theSign, theDollars, theCents);
}

void Currency::setValue(SignType theSign, unsigned long theDollars, unsigned int theCents)
{
    if (theCents > 99)
    {
        throw illegalParameterValue("Cents should be < 100");
    }
    amount = theDollars * 100 + theCents;
    if (theSign == SignType::minus)
    {
        amount = -amount;
    }
}

void Currency::setValue(double theAmount)
{
    if (theAmount < 0)
    {
        amount = (long) ((theAmount - 0.001) * 100);
    }
    else
    {
        amount = (long) ((theAmount + 0.001) * 100);
    }
}

Currency Currency::operator+(const Currency &x) const
{
    Currency y;
    y.amount = amount + x.amount;
    return y;
}

void Currency::output(ostream &out) const
{
    long theAmount = amount;
    if (theAmount < 0)
    {
        out << '-';
        theAmount = -theAmount;
    }
    long dollars = theAmount / 100;
    out << '$' << dollars << '.';
    int cents = theAmount - dollars * 100;
    if (cents < 10)
    {
        out << '0';
    }
    out << cents;
}

ostream &operator<<(ostream &out, const Currency &x)
{
    x.output(out);
    return out;
}

int main()
{
    Currency g, h(SignType::plus, 3, 50), i, j;
    g.setValue(SignType::minus, 2, 25);
    i.setValue(-6.45);
    j = h + g;
    std::cout << h << " + " << g << " = " << j << std::endl;

    j = i + g + h;
    std::cout << i << " + " << g << " + " << h << " = " << j << std::endl;

    std::cout << "Increment " << i << " by" << g << " and the add " << h << std::endl;
    j = ( i += g) + h;
    std::cout << "Result is " << j << std::endl;
    std::cout << "Incremented object is " << i << std::endl;

    std::cout << "Attempting to initialize with cents = 152" << std::endl;
    try
    {
        i.setValue(SignType::plus, 3, 152);
    }
    catch (illegalParameterValue &e)
    {
        std::cout << "Caught thrown exception" << endl;
        e.outputMessage();
    }
    return 0;
}
